"""
This simple animation example shows how to use classes to animate
multiple objects on the screen at the same time.

Note: Sprites draw much faster than drawing primitives

If Python and Arcade are installed, this example can be run from the command line with:
python -m arcade.examples.shapes
"""

import arcade
import random
import math

# Set up the constants
WINDOW_WIDTH = 1280
WINDOW_HEIGHT = 720
WINDOW_TITLE = "Shapes!"

NUMBER_OF_SHAPES = 200


class Shape:
    """ Generic base shape class """
    def __init__(self, x, y, width, height, angle, delta_x, delta_y,
                 delta_angle, color):
        # 随机形状
        # x,y表示中心坐标，根据delta_x和delta_y进行移动
        self.x = x
        self.y = y
        # width,height表示宽高
        self.width = width
        self.height = height
        # angle表示角度，根据delta_angle变化
        self.angle = angle
        # delta_x,delta_y表示移动坐标参数
        self.delta_x = delta_x
        self.delta_y = delta_y
        # delta_angle表示旋转角度
        self.delta_angle = delta_angle
        # color表示颜色
        self.color = color

    def move(self):
        self.x += self.delta_x
        self.y += self.delta_y
        self.angle += self.delta_angle
        # 如果超出边界，则移动距离取反（仅考虑中心距离）
        if self.x < 0 and self.delta_x < 0:
            self.delta_x *= -1
        if self.y < 0 and self.delta_y < 0:
            self.delta_y *= -1
        if self.x > WINDOW_WIDTH and self.delta_x > 0:
            self.delta_x *= -1
        if self.y > WINDOW_HEIGHT and self.delta_y > 0:
            self.delta_y *= -1


class Ellipse(Shape):

    def draw(self):
        # 椭圆绘画
        arcade.draw_ellipse_filled(self.x, self.y, self.width, self.height,
                                   self.color, self.angle)


class Rectangle(Shape):

    def draw(self):
        # 方形绘画
        arcade.draw_rect_filled(arcade.rect.XYWH(self.x, self.y, self.width, self.height),
                                self.color, self.angle)


class Line(Shape):

    def draw(self):
        # 线绘画
        arcade.draw_line(self.x, self.y,
                         self.x + self.width, self.y + self.height,
                         self.color, 2)


class Triangle(Shape):

    def draw(self):
        # 三角形绘画（实际是个直角三角形）
        # arcade.draw_triangle_filled(self.x, self.y, 
        #                             self.x + self.width, self.y,
        #                             self.x, self.y + self.height, 
        #                             self.color)
        # 如果要三角形形状完全随机，可以x,y为原型，随机设置3个弧度，根据这3个弧度，计算对应的点，构建为三角形（如此还可以避免3个点在一条直线上）
        # 但随机计算应该在update时执行，而非draw。draw出的图形必定是稳定的。
        # r=(self.width+self.height)//2
        # rad1=random.random()*math.pi * 2
        # rad2=random.random()*math.pi * 2
        # rad3=random.random()*math.pi * 2
        # x1 = self.x + r * math.cos(rad1)
        # y1 = self.y + r * math.sin(rad1)
        # x2 = self.x + r * math.cos(rad2)
        # y2 = self.y + r * math.sin(rad2)
        # x3 = self.x + r * math.cos(rad3)
        # y3 = self.y + r * math.sin(rad3)
        # 此处化的是等腰三角形（且稳定）
        x1=self.x
        y1=self.y+self.height/2
        x2=self.x-self.width/2
        y2=self.y-self.height/2
        x3=self.x+self.width/2
        y3=self.y-self.height/2
        arcade.draw_triangle_filled(x1, y1, x2, y2, x3, y3, self.color)


class GameView(arcade.View):
    """ Main application class. """

    def __init__(self):
        # Call the parent __init__
        super().__init__()

        # Create a shape list
        self.shape_list = []

        # 创建200个形状
        for i in range(NUMBER_OF_SHAPES):

            # Random spot
            # x,y坐标随机
            x = random.randrange(0, WINDOW_WIDTH)
            y = random.randrange(0, WINDOW_HEIGHT)

            # Random size
            # 尺寸在15px到39px之间
            width = random.randrange(15, 40)
            height = random.randrange(15, 40)

            # Random angle
            # 角度从0到360任意取值
            angle = random.randrange(0, 360)

            # Random movement
            # 移动的速度从-3到3之间随机分布
            d_x = random.randrange(-3, 4)
            d_y = random.randrange(-3, 4)
            d_angle = random.randrange(-3, 4)

            # Random color
            # 随机颜色和透明度
            red = random.randrange(256)
            green = random.randrange(256)
            blue = random.randrange(256)
            alpha = random.randrange(256)

            # Random line, ellipse, or rect
            # 形状随机取值
            shape_type = random.randrange(4)

            if shape_type == 0:
                shape = Rectangle(x, y, width, height, angle, d_x, d_y,
                                  d_angle, (red, green, blue, alpha))
            elif shape_type == 1:
                shape = Ellipse(x, y, width, height, angle, d_x, d_y,
                                d_angle, (red, green, blue, alpha))
            elif shape_type ==2 :
                shape = Line(x, y, width, height, angle, d_x, d_y,
                             d_angle, (red, green, blue, alpha))
            else:
                shape = Triangle(x, y, width, height, angle, d_x, d_y,
                                 d_angle, (red, green, blue, alpha))

            # Add this new shape to the list
            self.shape_list.append(shape)

    def on_update(self, dt):
        """ Move everything """
        # 形状移动
        for shape in self.shape_list:
            shape.move()

    def on_draw(self):
        """ Render the screen. """
        self.clear()

        # Draw the shapes
        # 形状绘画
        for shape in self.shape_list:
            shape.draw()


def main():
    """ Main function """
    # Create a window class. This is what actually shows up on screen
    window = arcade.Window(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_TITLE)

    # Create the GameView
    game = GameView()

    # Show GameView on screen
    window.show_view(game)

    # Start the arcade game loop
    arcade.run()


if __name__ == "__main__":
    main()